package com.softgroup.breath.easyecgproject.activity;


import android.Manifest;
import android.annotation.SuppressLint;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.provider.MediaStore;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.KeyEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewTreeObserver;
import android.webkit.JavascriptInterface;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ViewSwitcher;

import com.softgroup.breath.easyecgproject.R;
import com.softgroup.breath.easyecgproject.entry.CommandInfo;
import com.softgroup.breath.easyecgproject.entry.UserInfo;
import com.softgroup.breath.easyecgproject.myapi.HeartRateCount;
import com.softgroup.breath.easyecgproject.myapi.MyOkHttpTask;
import com.softgroup.breath.easyecgproject.service.BluetoothLeService;
import com.softgroup.breath.easyecgproject.utils.DataManager;
import com.softgroup.breath.easyecgproject.utils.DialogUtil;
import com.softgroup.breath.easyecgproject.utils.SettingManager;
import com.softgroup.breath.easyecgproject.windowbase.ToastUtil;

import java.io.File;
import java.io.FileInputStream;
import java.security.cert.Certificate;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import static com.softgroup.breath.easyecgproject.activity.MainActivity.Retry.REWRITE_USER;
import static com.softgroup.breath.easyecgproject.entry.CommandInfo.getRealQuest;
import static com.softgroup.breath.easyecgproject.myapi.FormatCast.bytesToHexString;

public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback, View.OnClickListener {
    private final String TAG = MainActivity.class.getSimpleName();
    private SurfaceView surfaceView;
    private SurfaceHolder surfaceHolder;
    private BluetoothLeService mBluetoothLeService;
    private Timer timer;
    private TimerTask timerTask;
    private boolean isDrawing = true;
    private boolean isDrawVisible;
    private DataManager dataManager;
    private HeartRateCount heartRateCount;
    private Rect rect;
    private Rect rectBreathe;
    private Paint paintEcgLine;
    private Path pathEcgLine;
    private Path pathBreatheLine;
    private Paint paintEcgBackground;
    private Paint paintBreatheLine;
    private Paint paintFrame;
    private Paint paintText;
    private Path path1;
    private Path path2;
    private Path path3;
    private Path path4;
    private Path path5;
    private Path path6;
    private Path path7;
    private Path pathFrame;

    private boolean isSixChannel = true;
    private ViewTreeObserver vto;
    private int maxWidth;
    private int minHeight;
    private int maxHeight;
    private int sixWidth;
    private int sixHeight;
    private int breatheHeight;
    private int paddingWidth;
    private int paddingHeight;
    private int pageSize = 1200;
    private boolean isNewUser = false;
    public final static String DEFAULT_MAC = "00:81:F9:62:50:0A";
    public final static String DEFAULT_MAC1 = "B7:30:12:3F:92:4D";
    public final static String DEFAULT_MAC2 = "50:63:C2:EF:9E:7D";
    public final static String DEFAULT_MAC3 = "78:01:82:AF:98:32";
    public final static String DEFAULT_MAC4 = "EF:72:01:2D:E0:5B";
    private Context context = this;
    private boolean isConnect = false;

    private Retry rewriteUser;
    private CommandInfo commandInfo;

    private boolean isTesting = false;
    private SettingManager settingManager;

    private static int REQUEST_EXTERNAL_STORAGE = 101;
    private static final String[] PERMISSIONS = new String[]{
            Manifest.permission.ACCESS_COARSE_LOCATION,
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.READ_PHONE_STATE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.CAMERA};
    private static final int GPS_REQUEST_CODE = 1315;
    private LocationManager locationManager;
    private Location location;
    private ImageView im_ecgSwitch;
    private ImageView im_patientInfo;
    private ImageView im_carInfo;
    private ImageView im_testSetting;
    private ImageView im_pause;
    private ImageView im_standbyMode;
    private ImageView im_deviceSwitch;
    private UserInfo userInfo;
    private DialogUtil dialogUtil;
    private final int CAMERA_RESULT_CODE = 100;
    private final int CROP_RESULT_CODE = 101;


    private void initTimerTask() {
        if (timer != null) {
            if (timerTask != null) {
                timerTask.cancel();
            }
        }
        timerTask = new TimerTask() {
            @Override
            public void run() {
                try {
                    mBluetoothLeService.timerTask();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (isDrawing & isDrawVisible) {
                    int array[] = dataManager.getDrawArray();
                    Message msg = mHandler.obtainMessage();
                    msg.what = 0x0a;
                    msg.obj = array;
                    Bundle bundle = new Bundle();
                    bundle.clear();
                    bundle.putFloatArray("msg", dataManager.getDrawArrayH(0));
                    bundle.putFloatArray("msg1", dataManager.getDrawArrayH(1));
                    bundle.putFloatArray("msg2", dataManager.getDrawArrayH(2));
                    bundle.putFloatArray("msg3", dataManager.getDrawArrayH(3));
                    bundle.putFloatArray("msg4", dataManager.getDrawArrayH(4));
                    bundle.putFloatArray("msg5", dataManager.getDrawArrayH(5));
                    bundle.putFloatArray("msg6", dataManager.getDrawArrayH(6));
                    bundle.putFloatArray("msg7", dataManager.getDrawArrayL());
                    msg.setData(bundle);
                    mHandler.sendMessage(msg);
                }
            }
        }; // 新建一个任务
        timer.schedule(timerTask, 1000, 60);
    }

    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            Bundle bundle = msg.getData();
            switch (msg.what) {
                case 0x0a:
                    drawSurface(bundle);
                    break;
                default:
                    break;
            }
            super.handleMessage(msg);
        }
    };
    private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, final Intent intent) {
            final String action = intent.getAction();
            if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) {

            } else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) {
                dataManager.setKnow(false);
                dataManager.setDeviceGatherState("未知");
            } else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) {
                mBluetoothLeService.writeCommand(10);
                isConnect = true;
                dataManager.setKnow(false);
                dataManager.setDeviceGatherState("未知");
                writeUser();
                Log.e("aadd", "connect");
                // Show all the supported services and characteristics on the user interface.
            } else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) {

            } else if (BluetoothLeService.ACTION_GATT_RSSI.equals(action)) {

            } else if (BluetoothLeService.ACTION_SCAN_FINISHED.equals(action)) {

            } else if (BluetoothLeService.ACTION_SOCKET_CALLBACK.equals(action)) {

            }
        }
    };
    private final ServiceConnection mServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder service) {
            mBluetoothLeService = ((BluetoothLeService.LocalBinder) service).getService();
            if (!mBluetoothLeService.initialize()) {
                finish();
            }
            mBluetoothLeService.enableBluetooth(true);
            mBluetoothLeService.connect(DEFAULT_MAC4);
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            mBluetoothLeService = null;
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        commandInfo = CommandInfo.getInstance(context);
        heartRateCount = new HeartRateCount();
        heartRateCount.initHeartRateCount();
        settingManager = SettingManager.getInstance();
        setContentView(R.layout.activity_first);
        dataManager = DataManager.getInstance();
        dataManager.initDataManager(1, settingManager.getTestDuration() * 6);
        initView();
        initDrawUtil();
        Intent service = new Intent(this, BluetoothLeService.class);
        bindService(service, mServiceConnection, Context.BIND_AUTO_CREATE);
        registerReceiver(mGattUpdateReceiver, makeGattUpdateIntentFilter());
        timer = new Timer();
        initTimerTask();
        checkPermission();
        userInfo = new UserInfo();
        userInfo.setUsername(settingManager.getUserName());
        userInfo.setUserage(settingManager.getUserAge());
        userInfo.setUsersex(settingManager.getUserSex());

//        Intent intent = new Intent(this, MyDaemonService.class);
//        startService(intent);

    }


    @Override
    protected void onResume() {
        super.onResume();
        isDrawVisible = true;
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_EXTERNAL_STORAGE) {
            initGPS();
        }
    }

    private void initGPS() {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return;
        }
        Criteria criteria = new Criteria();
        criteria.setAccuracy(Criteria.ACCURACY_FINE);
        criteria.setAltitudeRequired(true);
        criteria.setBearingRequired(true);
        criteria.setCostAllowed(true);
        criteria.setPowerRequirement(Criteria.POWER_LOW);
        String bestProvider = locationManager.getBestProvider(criteria, true);
        location = locationManager.getLastKnownLocation(bestProvider);
        LocationListener locationListener = new LocationListener() {

            @Override
            public void onLocationChanged(Location location) {
                updateLocation(location);
            }

            @Override
            public void onProviderDisabled(String arg0) {
            }

            @Override
            public void onProviderEnabled(String arg0) {
            }

            @Override
            public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
            }
        };
        locationManager.requestLocationUpdates(bestProvider, 5000, 0, locationListener);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == GPS_REQUEST_CODE) {
            if (!locationManager.isProviderEnabled(android.location.LocationManager.GPS_PROVIDER)) {
                Toast.makeText(this, "系统检测到未开启GPS定位服务,请开启", Toast.LENGTH_SHORT).show();
                finish();
            } else {
                initGPS();
            }
        } else if (requestCode == CAMERA_RESULT_CODE) {
            File tempFile = new File("/storage/emulated/0/Pictures/" + settingManager.getSessionID() + ".png");
            cropPic(Uri.fromFile(tempFile));
        } else if (requestCode == CROP_RESULT_CODE) {
            sendPicture();
        }
    }

    private String filePath = "/storage/emulated/0/Pictures/";
    private String filePath1 = "/storage/emulated/0/Pictures/Screenshots/";

    private void cropPic(Uri data) {
        if (data == null) {
            return;
        }
        Intent cropIntent = new Intent("com.android.camera.action.CROP");
        cropIntent.setDataAndType(data, "image/*");

        // 开启裁剪：打开的Intent所显示的View可裁剪
        cropIntent.putExtra("crop", "true");
        // 裁剪宽高比
        cropIntent.putExtra("aspectX", 1);
        cropIntent.putExtra("aspectY", 1);
        // 裁剪输出大小
        cropIntent.putExtra("outputX", 240);
        cropIntent.putExtra("outputY", 240);
        cropIntent.putExtra("scale", true);
        /**
         * return-data
         * 这个属性决定我们在 onActivityResult 中接收到的是什么数据，
         * 如果设置为true 那么data将会返回一个bitmap
         * 如果设置为false，则会将图片保存到本地并将对应的uri返回，当然这个uri得有我们自己设定。
         * 系统裁剪完成后将会将裁剪完成的图片保存在我们所这设定这个uri地址上。我们只需要在裁剪完成后直接调用该uri来设置图片，就可以了。
         */
        cropIntent.putExtra("return-data", false);
        // 当 return-data 为 false 的时候需要设置这句
        cropIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(filePath1 + settingManager.getSessionID() + ".png")));
        // 图片输出格式
        cropIntent.putExtra("outputFormat", Bitmap.CompressFormat.PNG.toString());
        // 头像识别 会启动系统的拍照时人脸识别
        cropIntent.putExtra("noFaceDetection", true);
        startActivityForResult(cropIntent, CROP_RESULT_CODE);
    }


    private void sendPicture() {
        MyOkHttpTask myOkHttpTask = new MyOkHttpTask(context);
        myOkHttpTask.execute(new String[]{"1", filePath1 + settingManager.getSessionID() + ".png"});
    }

    private void openSysCamera() {
        Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(
                new File(filePath, SettingManager.getInstance().getSessionID() + ".png")));
        startActivityForResult(cameraIntent, CAMERA_RESULT_CODE);
    }


    private void updateLocation(Location location) {
//        Log.e(TAG, "定位对象信息如下：" + location.toString() + "\n\t其中经度：" + location.getLongitude() + "\n\t其中纬度："
//                + location.getLatitude());
        settingManager.setGPS(location.getLongitude(), location.getLatitude());
        dataManager.setGps(location.getLongitude(), location.getLatitude());
    }

    private void checkPermission() {
        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
            Toast.makeText(this, "系统检测到未开启GPS定位服务,请开启", Toast.LENGTH_SHORT).show();
            Intent intent = new Intent();
            intent.setAction(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
            startActivityForResult(intent, GPS_REQUEST_CODE);
        }
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED |
                ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            //用户已经拒绝过一次，再次弹出权限申请对话框需要给用户一个解释
            if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) |
                    ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)) {
                Toast.makeText(this, "请开通相关权限，否则无法正常使用本应用！", Toast.LENGTH_SHORT).show();
            }
            ActivityCompat.requestPermissions(this, PERMISSIONS, REQUEST_EXTERNAL_STORAGE);
        } else {
            initGPS();
        }
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.im_patient_info:
                dialogUtil.showUserSetting();
                break;
            case R.id.im_car_info:
                dialogUtil.showCarInfo();
                break;
            case R.id.im_test_setting:
                dialogUtil.showTestSetting();
                break;
            case R.id.im_ecg_switch:
                if (!isDrawVisible) {
                    isDrawVisible = true;
                }
                isSixChannel = !isSixChannel;
                if (!isSixChannel) {
                    ToastUtil.getInstance().showToast(5);
                } else {
                    ToastUtil.getInstance().showToast(6);
                }

                break;
            case R.id.im_pause:
                isDrawing = !isDrawing;
                if (!isDrawing) {
                    ToastUtil.getInstance().showToast(3);
                } else {
                    ToastUtil.getInstance().showToast(4);
                }
                break;
            case R.id.im_standby_mode:
                if (dataManager.isTransport()) {
                    dialogUtil.showConfirm(DialogUtil.MODE_STANDBY);
                } else {
                    dialogUtil.showConfirm(DialogUtil.MODE_START);
                }
                break;
            case R.id.im_device_switch:
                ToastUtil.getInstance().showToast(7);
                break;
        }
    }

    private void initView() {
        dialogUtil = DialogUtil.getInstance(context);
        dialogUtil.setOnConfirmListener(new DialogUtil.OnConfirmListener() {
            @Override
            public void onConfirm(int mode) {
                switch (mode) {
                    case DialogUtil.MODE_STANDBY:
                        setCommand(10);
                        break;
                    case DialogUtil.MODE_START:
                        writeUser();
                        break;
                }
            }

            @Override
            public void onRefuse(int mode) {

            }

            @Override
            public void onUser(UserInfo userInfo1) {
                userInfo = userInfo1;
                MyOkHttpTask myOkHttpTask = new MyOkHttpTask(context);
                myOkHttpTask.execute(new String[]{"0", userInfo.getUsername(), userInfo.getUsersex(), userInfo.getUserage()});
                settingManager.setUserName(userInfo.getUsername());
                settingManager.setUserSex(userInfo.getUsersex());
                settingManager.setUserAge(userInfo.getUserage());
            }

            @Override
            public void onTake() {
                openSysCamera();
            }
        });
        im_patientInfo = findViewById(R.id.im_patient_info);
        im_patientInfo.setOnClickListener(this);
        im_carInfo = findViewById(R.id.im_car_info);
        im_carInfo.setOnClickListener(this);
        im_testSetting = findViewById(R.id.im_test_setting);
        im_testSetting.setOnClickListener(this);
        im_ecgSwitch = findViewById(R.id.im_ecg_switch);
        im_ecgSwitch.setOnClickListener(this);
        im_pause = findViewById(R.id.im_pause);
        im_pause.setOnClickListener(this);
        im_standbyMode = findViewById(R.id.im_standby_mode);
        im_standbyMode.setOnClickListener(this);
        im_deviceSwitch = findViewById(R.id.im_device_switch);
        im_deviceSwitch.setOnClickListener(this);
        surfaceView = findViewById(R.id.sfv_main);
        surfaceHolder = surfaceView.getHolder();
        vto = surfaceView.getViewTreeObserver();
        vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            public void onGlobalLayout() {
                surfaceView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                maxWidth = surfaceView.getWidth();
                sixWidth = maxWidth * 2 / 5;
                Log.e(TAG, "sixHeight" + sixHeight);
                maxHeight = surfaceView.getHeight();
                sixHeight = maxHeight * 2 / 15;
                breatheHeight = maxHeight / 5;
                paddingWidth = maxWidth / 20;
                paddingHeight = maxHeight / 30;
                rect = new Rect(0, 0, maxWidth, maxHeight);
                rectBreathe = new Rect(0, maxHeight / 2, maxWidth, maxHeight);
                minHeight = 0;
            }
        });
        dataManager.setAnswerCallBack(new DataManager.AnswerCallback() {
            @Override
            public void onAnswer(String s) {

            }

            @Override
            public void onPageIsMeet() {

            }

            @Override
            public void onDataPageCallBack() {
                dataManager.setHrs(heartRateCount.getHrs());
                mBluetoothLeService.dataCallBack(dataManager.getSendDataPage());
                heartRateCount.initSub1();
            }

            @Override
            public void onPowerLow() {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(context, "电池电量低，请充电", Toast.LENGTH_SHORT);
                    }
                });
            }

            @Override
            public void onDeviceStateChange() {
                setCommand(2);
            }

            @Override
            public void onUserBond(boolean isSuccess) {
                if (isSuccess) {
                    mBluetoothLeService.writeCommand(9);
                }
            }

            @Override
            public void onBreakTransport() {

            }

            @Override
            public void onInit() {
                writeUser();
//                mBluetoothLeService.writeCommand(getRealQuest(12) + bytesToHexString(settingManager.getUser().getBytes()));
                Log.e("device_results", "onInit");
            }

            @Override
            public void onIsGathering() {
                mBluetoothLeService.writeCommand("E8200136EE80");
                isNewUser = false;
                Log.e("device_results", "isGather");
            }

            @Override
            public void onIsTransport() {
                Log.e("device_results", "isTransport");
            }
        });
    }


    private long firstTime = 0;

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) {
            if (System.currentTimeMillis() - firstTime > 2000) {
                Toast.makeText(context, "再次点击退出应用", Toast.LENGTH_SHORT).show();
                firstTime = System.currentTimeMillis();
            } else {
                finish();
                System.exit(0);
            }
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

    private void initDrawUtil() {
        paintEcgLine = new Paint();
        paintEcgLine.setAntiAlias(true);
        paintEcgLine.setColor(0xFF00ff00);
        paintEcgLine.setStrokeWidth(1);
        paintEcgLine.setTextSize(30);
        paintEcgLine.setStyle(Paint.Style.STROKE);
        paintEcgBackground = new Paint();
        paintEcgBackground.setColor(0xFF000000);
        paintEcgBackground.setTextSize(maxHeight * 6 / 60);
        paintEcgBackground.setAntiAlias(true);
        paintBreatheLine = new Paint();
        paintBreatheLine.setAntiAlias(true);
        paintBreatheLine.setColor(0xFFFF00FF);
        paintBreatheLine.setStrokeWidth(3);
        paintBreatheLine.setStyle(Paint.Style.STROKE);
        paintBreatheLine.setTextAlign(Paint.Align.CENTER);
        paintBreatheLine.setTextSize(70);
        paintFrame = new Paint();
        paintFrame.setAntiAlias(true);
        paintFrame.setColor(0xFFffff00);
        paintFrame.setStrokeWidth(1);
        paintFrame.setTextSize(30);
        paintFrame.setStyle(Paint.Style.STROKE);
        paintText = new Paint();
        paintText.setAntiAlias(true);
        paintText.setTextSize(30);
        paintText.setColor(0xff0000ff);
        paintText.setStrokeWidth(2);
        paintText.setTextAlign(Paint.Align.CENTER);
        pathEcgLine = new Path();
        pathBreatheLine = new Path();
        path1 = new Path();
        path2 = new Path();
        path3 = new Path();
        path4 = new Path();
        path5 = new Path();
        path6 = new Path();
        path7 = new Path();
        pathFrame = new Path();
    }

    private void drawSurface(Bundle bundle) {
        Canvas canvas = surfaceHolder.lockCanvas();
        try {
            if (isDrawing) {
                if (isDrawVisible) {
                    canvas.drawRect(rect, paintEcgBackground);
                    canvas.drawText("姓名：" + userInfo.getUsername(), paddingWidth * 3 / 2, paddingHeight * 4, paintText);
                    canvas.drawText("性别：" + userInfo.getUsersex(), paddingWidth * 3 / 2, paddingHeight * 6, paintText);
                    canvas.drawText("年龄：" + userInfo.getUserage(), paddingWidth * 3 / 2, paddingHeight * 8, paintText);
                    canvas.drawLine(15, paddingHeight * 3f, paddingWidth * 3 - 15, paddingHeight * 3f, paintBreatheLine);
                    canvas.drawLine(15, paddingHeight * 8.2f, paddingWidth * 3 - 15, paddingHeight * 8.2f, paintBreatheLine);
                    canvas.drawLine(15, paddingHeight * 12, paddingWidth * 3 - 15, paddingHeight * 12, paintBreatheLine);
                    canvas.drawLine(15, paddingHeight * 18, paddingWidth * 3 - 15, paddingHeight * 18, paintBreatheLine);
                    canvas.drawLine(15, paddingHeight * 21.8f, paddingWidth * 3 - 15, paddingHeight * 21.8f, paintBreatheLine);
                    canvas.drawLine(15, paddingHeight * 27.8f, paddingWidth * 3 - 15, paddingHeight * 27.8f, paintBreatheLine);
                    canvas.drawText("心率（次/分）", paddingWidth * 3 / 2, paddingHeight * 13, paintText);
                    canvas.drawText("呼吸（次/分）", paddingWidth * 3 / 2, paddingHeight * 22.8f, paintText);
                    canvas.drawText("12", paddingWidth * 3 / 2, paddingHeight * 25.8f, paintBreatheLine);
                    canvas.drawLine(paddingWidth * 3 - 5, 0, paddingWidth * 3 - 5, maxHeight, paintBreatheLine);
                    canvas.drawLine(5, 0, 5, maxHeight, paintBreatheLine);
                }
                float array0[] = bundle.getFloatArray("msg");
                float array1[] = bundle.getFloatArray("msg1");
                float array2[] = bundle.getFloatArray("msg2");
                float array3[] = bundle.getFloatArray("msg3");
                float array4[] = bundle.getFloatArray("msg4");
                float array5[] = bundle.getFloatArray("msg5");
                float array6[] = bundle.getFloatArray("msg6");
                float array7[] = bundle.getFloatArray("msg7");
                pathEcgLine.reset();
                path1.reset();
                path2.reset();
                path3.reset();
                path4.reset();
                path5.reset();
                path6.reset();
                path7.reset();
                if (!isSixChannel) {
                    if (array0 != null) {
                        for (int i = 0; i < array1.length; i++) {
                            float y = array1[i] * maxWidth / 15f;
                            if (y > breatheHeight) {
                                y = breatheHeight;
                            } else if (y < -breatheHeight) {
                                y = -breatheHeight;
                            }
                            float y1 = (array7[i] - array7[0]) * 1000;
                            if (y1 > breatheHeight) {
                                y1 = breatheHeight;
                            } else if (y1 < -breatheHeight) {
                                y1 = -breatheHeight;
                            }
                            if (i == 0) {
                                pathEcgLine.moveTo(paddingWidth * 3, (maxHeight + minHeight) / 4 - y + maxHeight / 20);
                                path7.moveTo(paddingWidth * 3, (maxHeight + minHeight) * 3 / 4 - y1 + maxHeight / 20);
                            } else {
                                pathEcgLine.lineTo(i * (maxWidth - paddingWidth * 3) / pageSize + paddingWidth * 3, (maxHeight + minHeight) / 4 - y + maxHeight / 20);
                                path7.lineTo(i * (maxWidth - paddingWidth * 3) / pageSize + paddingWidth * 3, (maxHeight + minHeight) * 3 / 4 - y1 + maxHeight / 20);
                            }
                        }
                    }
                    canvas.drawPath(pathEcgLine, paintEcgLine);
                    canvas.drawPath(path7, paintEcgLine);
                    canvas.drawText("心电图：", paddingWidth * 4, paddingHeight * 2 - 5, paintText);
                    canvas.drawText("呼吸波：", paddingWidth * 4, maxHeight / 2 + paddingHeight * 2 - 5, paintText);
                } else {
                    if (array1 != null) {
                        for (int i = 0; i < array1.length; i++) {
                            float y1 = array1[i] * maxWidth / 25f;
                            float y2 = array2[i] * maxWidth / 25f;
                            float y3 = array3[i] * maxWidth / 25f;
                            float y4 = array4[i] * maxWidth / 25f;
                            float y5 = array5[i] * maxWidth / 25f;
                            float y6 = array6[i] * maxWidth / 25f;

                            if (y1 > sixHeight) {
                                y1 = sixHeight;
                            } else if (y1 < -sixHeight) {
                                y1 = -sixHeight;
                            }
                            if (y2 > sixHeight) {
                                y2 = sixHeight;
                            } else if (y2 < -sixHeight) {
                                y2 = -sixHeight;
                            }
                            if (y3 > sixHeight) {
                                y3 = sixHeight;
                            } else if (y3 < -sixHeight) {
                                y3 = -sixHeight;
                            }
                            if (y4 > sixHeight) {
                                y4 = sixHeight;
                            } else if (y4 < -sixHeight) {
                                y4 = -sixHeight;
                            }
                            if (y5 > sixHeight) {
                                y5 = sixHeight;
                            } else if (y5 < -sixHeight) {
                                y5 = -sixHeight;
                            }
                            if (y6 > sixHeight) {
                                y6 = sixHeight;
                            } else if (y6 < -sixHeight) {
                                y6 = -sixHeight;
                            }
                            if (i == 0) {
                                path1.moveTo(i * sixWidth / pageSize + maxWidth / 20 + paddingWidth * 2, (maxHeight + minHeight) / 6 - y1 + paddingHeight);
                                path2.moveTo(i * sixWidth / pageSize + maxWidth / 2 + maxWidth / 20 + paddingWidth, (maxHeight + minHeight) / 6 - y2 + paddingHeight);
                                path3.moveTo(i * sixWidth / pageSize + maxWidth / 20 + paddingWidth * 2, (maxHeight + minHeight) / 2 - y3 + paddingHeight);
                                path4.moveTo(i * sixWidth / pageSize + maxWidth / 2 + paddingWidth + maxWidth / 20, (maxHeight + minHeight) / 2 - y4 + paddingHeight);
                                path5.moveTo(i * sixWidth / pageSize + maxWidth / 20 + paddingWidth * 2, (maxHeight + minHeight) * 5 / 6 - y5 + paddingHeight);
                                path6.moveTo(i * sixWidth / pageSize + maxWidth / 2 + paddingWidth + maxWidth / 20, (maxHeight + minHeight) * 5 / 6 - y6 + paddingHeight);
                            }
                            path1.lineTo(i * sixWidth / pageSize + maxWidth / 20 + paddingWidth * 2, (maxHeight + minHeight) / 6 - y1 + paddingHeight);
                            path2.lineTo(i * sixWidth / pageSize + maxWidth / 2 + maxWidth / 20 + paddingWidth, (maxHeight + minHeight) / 6 - y2 + paddingHeight);
                            path3.lineTo(i * sixWidth / pageSize + maxWidth / 20 + paddingWidth * 2, (maxHeight + minHeight) / 2 - y3 + paddingHeight);
                            path4.lineTo(i * sixWidth / pageSize + maxWidth / 2 + maxWidth / 20 + paddingWidth, (maxHeight + minHeight) / 2 - y4 + paddingHeight);
                            path5.lineTo(i * sixWidth / pageSize + maxWidth / 20 + paddingWidth * 2, (maxHeight + minHeight) * 5 / 6 - y5 + paddingHeight);
                            path6.lineTo(i * sixWidth / pageSize + maxWidth / 2 + maxWidth / 20 + paddingWidth, (maxHeight + minHeight) * 5 / 6 - y6 + paddingHeight);
                        }
                    }
                    if (isDrawVisible) {
                        canvas.drawPath(path1, paintEcgLine);
                        canvas.drawPath(path2, paintEcgLine);
                        canvas.drawPath(path3, paintEcgLine);
                        canvas.drawPath(path4, paintEcgLine);
                        canvas.drawPath(path5, paintEcgLine);
                        canvas.drawPath(path6, paintEcgLine);
                    }
                }
            }
            drawFrame(canvas, isSixChannel);
            int progress = dataManager.getProgress();
            if (dataManager.getSubscript() > 200 & dataManager.getProgressSecond() != 0) {
                heartRateCount.getHeartRate(dataManager.getHeartCountArray(), dataManager.getHeartCountArray().length, true);
                if (isDrawVisible) {
                    canvas.drawText(heartRateCount.getRealTimeHeartRate() + "", paddingWidth * 3 / 2, paddingHeight * 16, paintBreatheLine);
                }
            }


        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                surfaceHolder.unlockCanvasAndPost(canvas);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    private void drawFrame(Canvas canvas, boolean isSixChannel) {
        if (isSixChannel) {
            for (int i = 0; i < 6; i++) {
                pathFrame.reset();
                pathFrame.moveTo(paddingWidth * 2 + paddingWidth * ((i + 1) % 2) + i % 2 * maxWidth / 2, paddingHeight * 2 + i / 2 * maxHeight / 3);
                pathFrame.lineTo(maxWidth / 2 + paddingWidth * ((i + 1) % 2) + i % 2 * maxWidth / 2, paddingHeight * 2 + i / 2 * maxHeight / 3);
                pathFrame.lineTo(maxWidth / 2 + paddingWidth * ((i + 1) % 2) + i % 2 * maxWidth / 2, maxHeight / 3 + i / 2 * maxHeight / 3);
                pathFrame.lineTo(paddingWidth * 2 + paddingWidth * ((i + 1) % 2) + i % 2 * maxWidth / 2, maxHeight / 3 + i / 2 * maxHeight / 3);
                pathFrame.close();
                canvas.drawPath(pathFrame, paintFrame);
            }
            for (int i = 0; i < 6; i++) {
                pathFrame.reset();
                pathFrame.moveTo(paddingWidth * 4 + i % 2 * (sixWidth + paddingWidth), maxHeight / 6 + i / 2 * maxHeight / 3 + paddingHeight);
                pathFrame.lineTo(paddingWidth * 4.2f + i % 2 * (sixWidth + paddingWidth), maxHeight / 6 + i / 2 * maxHeight / 3 + paddingHeight);
                pathFrame.lineTo(paddingWidth * 4.2f + i % 2 * (sixWidth + paddingWidth), maxHeight / 6 - paddingWidth / 2 + i / 2 * maxHeight / 3 + paddingHeight);
                pathFrame.lineTo(paddingWidth * 4.4f + i % 2 * (sixWidth + paddingWidth), maxHeight / 6 - paddingWidth / 2 + i / 2 * maxHeight / 3 + paddingHeight);
                pathFrame.lineTo(paddingWidth * 4.4f + i % 2 * (sixWidth + paddingWidth), maxHeight / 6 + i / 2 * maxHeight / 3 + paddingHeight);
                pathFrame.lineTo(paddingWidth * 4.6f + i % 2 * (sixWidth + paddingWidth), maxHeight / 6 + i / 2 * maxHeight / 3 + paddingHeight);
                canvas.drawPath(pathFrame, paintBreatheLine);
            }
        } else {
            for (int i = 0; i < 2; i++) {
                pathFrame.reset();
                pathFrame.moveTo(paddingWidth * 3, maxHeight / 10 + maxHeight / 2 * i);
                pathFrame.lineTo(maxWidth, maxHeight / 10 + maxHeight / 2 * i);
                pathFrame.lineTo(maxWidth, maxHeight / 2 + maxHeight / 2 * i);
                pathFrame.lineTo(paddingWidth * 3, maxHeight / 2 + maxHeight / 2 * i);
                pathFrame.close();
                canvas.drawPath(pathFrame, paintFrame);
            }
            pathFrame.reset();
            pathFrame.moveTo(paddingWidth * 4 + maxHeight / 20, breatheHeight + maxHeight / 10);
            pathFrame.lineTo(paddingWidth * 4.3f + maxHeight / 20, breatheHeight + maxHeight / 10);
            pathFrame.lineTo(paddingWidth * 4.3f + maxHeight / 20, breatheHeight - paddingWidth + maxHeight / 10);
            pathFrame.lineTo(paddingWidth * 4.6f + maxHeight / 20, breatheHeight - paddingWidth + maxHeight / 10);
            pathFrame.lineTo(paddingWidth * 4.6f + maxHeight / 20, breatheHeight + maxHeight / 10);
            pathFrame.lineTo(paddingWidth * 4.9f + maxHeight / 20, breatheHeight + maxHeight / 10);
            canvas.drawPath(pathFrame, paintBreatheLine);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(mServiceConnection);
        unregisterReceiver(mGattUpdateReceiver);
    }

    private static IntentFilter makeGattUpdateIntentFilter() {
        final IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(BluetoothLeService.ACTION_GATT_CONNECTED);
        intentFilter.addAction(BluetoothLeService.ACTION_GATT_DISCONNECTED);
        intentFilter.addAction(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED);
        intentFilter.addAction(BluetoothLeService.ACTION_DATA_AVAILABLE);
        intentFilter.addAction(BluetoothLeService.ACTION_GATT_RSSI);
        intentFilter.addAction(BluetoothLeService.ACTION_SCAN_FINISHED);
        intentFilter.addAction(BluetoothLeService.ACTION_SOCKET_CALLBACK);
        return intentFilter;
    }


    private void writeUser() {
        isNewUser = true;
        dataManager.initDataManager(1, settingManager.getTestDuration() * 6);
        rewriteUser = new Retry(10000, 2000, REWRITE_USER);
        rewriteUser.start();
    }


    @Override
    public void surfaceCreated(SurfaceHolder holder) {

    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        maxWidth = surfaceView.getWidth();
        maxHeight = surfaceView.getHeight();
        rect = new Rect(0, 0, maxWidth, maxHeight);
        minHeight = 0;
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {

    }

    public void setCommand(int position) {
        mBluetoothLeService.writeCommand(position);
    }

    @Override
    protected void onPause() {
        super.onPause();
        isDrawVisible = false;
    }

    class Retry extends CountDownTimer {
        public final static int RECONNECT = 0;
        public final static int REWRITE_USER = 1;
        private int mode;

        public Retry(long milliInFuture, long countDwnInterval, int mode) {
            super(milliInFuture, countDwnInterval);
            this.mode = mode;
        }

        @Override
        public void onTick(long millisUntilFinished) {
            Log.e("device_results", "onTick");
            if (!isNewUser & !dataManager.isTransport()) {
                isNewUser = true;
            }
            if (mode == REWRITE_USER & isNewUser) {
                if (dataManager.isTransport() | dataManager.getDeviceGatherState().equals("就绪")) {
                    mBluetoothLeService.writeCommand(10);
                    Log.e("device_results", "stop");
                } else if (dataManager.getDeviceGatherState().equals("待机")) {
                    mBluetoothLeService.writeCommand(getRealQuest(12) + bytesToHexString(settingManager.getUser().getBytes()));
                    Log.e("device_results", "start");
                } else if (dataManager.getDeviceGatherState().equals("未知")) {
                    setCommand(2);
                    Log.e("device_results", "start");
                }
            }
        }

        @Override
        public void onFinish() {
            if (!isFinishing()) {
                if (mode == RECONNECT & !isConnect) {
                    //连接失败
                } else if (mode == REWRITE_USER) {
                    //装订失败
                }
            }
        }
    }
}
